package dk.contix.ant.gwt;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.FutureTask;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.dev.CompileTaskRunner;
import com.google.gwt.dev.Compiler;
import com.google.gwt.dev.CompilerOptions;
import com.google.gwt.dev.CompileTaskRunner.CompileTask;
import com.google.gwt.dev.jjs.JsOutputOption;
import com.google.gwt.dev.shell.CheckForUpdates;
import com.google.gwt.dev.shell.PlatformSpecific;

public class GWT16Compile implements CompilerOptions {

	private final CompileConfig config;
	private final Project project;

	public GWT16Compile(CompileConfig config, Project project) {
		this.config = config;
		this.project = project;
	}

	public void execute() {
	      CompileTask task = new CompileTask() {
	        public boolean run(TreeLogger logger) throws UnableToCompleteException {
	          FutureTask updater = null;
	          if (config.isOptimize()) {
	            updater = PlatformSpecific.checkForUpdatesInBackgroundThread(logger,
	                CheckForUpdates.ONE_DAY);
	          }
	          boolean success = new Compiler(GWT16Compile.this).run(logger);
	          if (success) {
	            PlatformSpecific.logUpdateAvailable(logger, updater);
	          }
	          return success;
	        }
	      };
	      if (CompileTaskRunner.runWithAppropriateLogger(this, task)) {
	    	  System.out.println("Compiled GWT modules");
	      }
		
	}

	public boolean isAggressivelyOptimize() {
		return true;
	}

	public void setAggressivelyOptimize(boolean aggressivelyOptimize) {}

	public boolean isEnableAssertions() {
		return false;
	}

	public void setEnableAssertions(boolean enableAssertions) {}

	public JsOutputOption getOutput() {
		return JsOutputOption.valueOf(config.getStyle().toUpperCase());
	}

	public void setOutput(JsOutputOption obfuscated) {}

	public boolean isUseGuiLogger() {
		return false;
	}

	public void setUseGuiLogger(boolean useGuiLogger) {}

	public void addModuleName(String moduleName) {}

	public List getModuleNames() {
		List res = new ArrayList();
		for (Iterator i = config.getFilesets().iterator(); i.hasNext();) {

			FileSet fs = (FileSet) i.next();
			DirectoryScanner ds = fs.getDirectoryScanner(project);
			String[] files = ds.getIncludedFiles();
			for (int j = 0; j < files.length; j++) {
				if (!files[j].endsWith(".gwt.xml")) {
					throw new BuildException("File " + files[j] + " is not a GWT file (.gwt.xml)");
				}
				String module = files[j].substring(0, files[j].indexOf('.')).replace(File.separatorChar, '.');
				if ((config.isOptimize() && Util.hasModifiedFiles(ds.getBasedir(), files[j], config.getDestdir())) || !config.isOptimize()) {
					res.add(module);
				} else {
					System.out.println("Skipping module " + module + ", no changed files found");
				}
			}
		}
		System.out.println("Comiling modules " + res);
		return res;
	}

	public void setModuleNames(List arg0) {}

	public Type getLogLevel() {
		if (config.getLevel() != null) {
			return Type.valueOf(config.getLevel());
		} else {
			return null;
		}
	}

	public void setLogLevel(Type logLevel) {}

	public File getWorkDir() {
		if (config.getWorkDir() != null) {
			return new File(config.getWorkDir());
		} else {
			return null;
		}
	}

	public void setWorkDir(File dir) {}

	public File getGenDir() {
		if (config.getGenDir() != null) {
			return new File(config.getGenDir());
		} else {
			return null;
		}
	}

	public void setGenDir(File dir) {}

	public boolean isValidateOnly() {
		return false;
	}

	public void setValidateOnly(boolean validateOnly) {}

	public boolean isUpdateCheckDisabled() {
		return !config.isOptimize();
	}

	public void setDisableUpdateCheck(boolean disabled) {}

	public File getExtraDir() {
		return null;
	}

	public void setExtraDir(File extraDir) {}

	public File getWarDir() {
		return new File(config.getDestdir());
	}

	public void setWarDir(File dir) {}

	public int getLocalWorkers() {
		return config.getWorkers();
	}

	public void setLocalWorkers(int localWorkers) {}
}
